#ifndef AZRECORD_H
#define AZRECORD_H

#include <QVector>
#include <QVariant>
#include <QXmlStreamWriter>
#include <QSharedDataPointer>

#include "Az.h"
#include "AzRecordData.h"

class AzRootRecord;
class AzAbstractDataSource;
class AzFieldList;

class AzRecordException: public AzException {
public:
    enum Error {
        RecordOutOfRangeError,
        RecordDataNotAccording,
        EmptyRecordDataError,
        RecordHasParentError,
        ChangeMetadataError
    };
    AzRecordException(Error err);
private:
    static QString codeToStr(Error);
    Error mErrCode;
};



class AzRecord {
    friend class AzAbstractDataSource;
public:
    typedef QVector<AzRecord*> RecordVectorPtr;

    enum RecordType {
        DataRecord      = 0x1,
        UserRecord      = 0x2
    };


    AzRecord(const AzRecord&);
    ~AzRecord();

    inline QVariant data(int i) const				{ return mRecordData.data(i);   }
    inline QVariant oldData(int i) const			{ return mRecordData.oldData(i);}

    const AzRecordValues& data() const            { return mRecordData.data();    }
    const AzRecordValues& oldData() const         { return mRecordData.oldData(); }

	void setData(int,const QVariant&);
    inline int size() const							{ return mRecordData.size(); }


    inline AzRecord *parent() const                 { return mParent;	}
    AzRecord *chaild(int i) const                   { return mClientRec[i]; }
    inline int childCount() const                   { return mClientRec.size(); }
    int childNumber() const;
    bool hasChaild(int);
    int level() const;
    bool hasModified() const;
    bool hasUnmodified() const;

    AzRecord* insert(int);
    AzRecord* insert(int, const AzRecordData&);

    AzRecord* append();
    AzRecord* append(const AzRecordData&);

    void remove(int);
    void deleteAll();

    inline void setRecordState(Az::RecordState state) { mRecordData.setRecordState(state); }
    inline Az::RecordState recordState() const			{ return mRecordData.recordState(); }

    const AzRootRecord *rootRec() const;

    static QString recordStateString(Az::RecordState);

protected:
    explicit AzRecord(RecordType = DataRecord);
    static AzRecord *createRecord(RecordType,const AzRecordData&);
    void insertColumn(int,QVariant::Type);

    AzRecordData mRecordData;

private:
    void insert(AzRecord*,int);
    void append(AzRecord* rec)                      { rec->insert(rec,size());}

    AzRootRecord *rootRec();
    void checkIsEnableChangeColumn() const;

    AzRecord *mParent;
    RecordType mRecordType;
    //RecordVectorPtr mOriginalRec;
    RecordVectorPtr mClientRec;
};
#endif // AZRECORD_H
